<!-- 只分配项目角色和当前项目站点 -->
<script setup>
import { ref, reactive, onMounted, watch, nextTick, h,computed } from 'vue';
import { iuserApi as MainApi, iuserById as MainById, roleApi, unitApi, positionApi } from '@T2/service/api.ts';
import { ElMessage, ElMessageBox } from 'element-plus';
import { useCurrentWatchStore, useIuserInfoStore } from '@T2/store/users.ts';
import { isPhone, buildTree, findNodeByProperty, buildPositionUnitTree } from '@T2/utils/utils.ts';
import { useRouter } from 'vue-router';
import { Md5 } from 'ts-md5';

const currentWatchStore = useCurrentWatchStore();
const { curProject,curMenus } = currentWatchStore;
const iuserInfoStore = useIuserInfoStore();
const { info, getHandleRight, admin_projects2 } = iuserInfoStore;
const RIGHT = getHandleRight(['312', '313', '314', '315', '316', '370']);
const router = useRouter();
const props = defineProps({
  node: {
    type: Object,
    required: true,
  },
  departmentIDList: {
    type: Array,
    required: true,
  },
  departmentTree: {
    type: Array,
    required: true,
  },
});

onMounted(() => {
  GetMainTable();
  getRoleTree();
});
watch(() => props.node.data.id, (nv, ov) => {
  if (nv || nv === 0) {
    MainTable.data = [];
    MainTable.total = 0;
    GetMainTable();
  }
});
const MainTable = reactive({
  data: [],
  total: 0,
});
const Filter = reactive({
  page: 1,
  pagesize: 30,
  search: '',
});
const showDepartments = computed(() => {
  let menus = curMenus.filter(item => item.type === 'PC-aside')
  let menuHave = menus.find(item => item.alias === '组织机构')
  return MainForm.departments_current?.length && menuHave ? true : false;
})
watch(() => ({...Filter}), (nv, ov) => {
  if (nv.page === 1 || nv.page !== ov.page) {
    GetMainTable();
  } else {
    Filter.page = 1;
  }
});
const GetMainTable = () => {
  MainApi({
    method: 'get',
    params: {
      ...Filter,
      identity__in: '无,业委会主任',
      departments: props.node.data.id || null,
      projects: curProject.id,
    }
  }).then(res => {
    MainTable.data = res?.results || [];
    MainTable.total = res?.count || 0;
  });
}
const Resd = reactive({
  roleList: [],
  roleTree: [],
});
const getRoleTree = () => {
  Resd.roleTree = [];
  roleApi({
    method: 'get',
    params: {
      ordering: 'id',
      project: curProject.id,
    }
  }).then(res => {
    Resd.roleList = res?.results || [];
    let arrs = buildTree(res.results || [], 'parent');
    Resd.roleTree = arrs;
  });
}
const filterOthers = (row, column, cellValue, index) => {
  if (curProject.admin_user === row.id) {
    return '项目管理员';
  }
  if (!cellValue) {
    return cellValue;
  }
  let text = '';
  const arrs = Resd.roleList.filter(i => cellValue.includes(i.id));
  return arrs.map(i => i.name).join(', ');
  
  
}

/* 新增编辑 */
const MainPopup = reactive({
  visible: false,
  type: '新增',
});
const MainForm = reactive({
  model: {},
  contract_old: '',
  departments_current: [],
  departments_others: [],
});
const MainFormRef = ref(null);
const ManiFormTreeRef = ref(null);
const handleMainAdd = (isAble = false) => {
  if (!isAble) {
    return;
  }
  MainPopup.visible = true;
  MainPopup.type = '新增';
  MainForm.model = {};
  MainForm.departments_current = [];
  nextTick(() => {
    MainFormRef.value.clearValidate();
  });
}
const handleMainEdit = (isAble = false, row) => {
  if (!isAble) {
    return;
  }
  MainPopup.visible = true;
  MainPopup.type = '编辑';
  MainForm.model = {
    id: row.id,
    truename: row.truename,
    contract: row.contract,
  };
  const departmentsIdsSet = new Set(props.departmentIDList);
  const departments_current = [];
  const departments_others = [];
  for (const dept of row.departments) {
    if (departmentsIdsSet.has(dept)) {
      departments_current.push(dept);
    } else {
      departments_others.push(dept);
    }
  }
  MainForm.departments_current = departments_current;
  MainForm.departments_others = departments_others;
  
  MainForm.contract_old = row.contract;
  nextTick(() => {
    MainFormRef.value.clearValidate();
  });
}
const handleMainSubmit = () => {
  MainFormRef.value.validate((valid) => {
    if (valid) {
      if (!isPhone(MainForm.model.contract)) {
        ElMessage.error('请输入正确的手机号');
        return;
      }
      MainPopup.visible = false;
      if (MainPopup.type === '新增') {
        AddMain();
      } else if (MainPopup.type === '编辑') {
        EditMain();
      }
    }
  });
}
const AddMain = () => {
  let auth_user_w = {
    password: Md5.hashStr('.ieieye.com' + MainForm.model.contract.substr(-6, 6) + 'shhengji'),
    username: MainForm.model.contract,
  };
  MainApi({
    method: 'post',
    data: {
      ...MainForm.model,
      auth_user_w,
      company: info.company,
      type: '项目用户',
      projects: [curProject.id],
    }
  }).then(res => {
    ElMessage.success('新增成功');
    GetMainTable();
  });
}
const EditMain = () => {
  let auth_user_w = {
    username: MainForm.model.contract,
  };
  if (MainForm.contract_old !== MainForm.model.contract) {
    auth_user_w.password = Md5.hashStr('.ieieye.com' + MainForm.model.contract.substr(-6, 6) + 'shhengji');
    ElMessage.warning('已修改登陆账号及密码！');
  }
  MainById({
    method: 'patch',
    id: MainForm.model.id,
    data: {
      ...MainForm.model,
      auth_user_w,
      departments: MainForm.departments_current.concat(MainForm.departments_others),
    }
  }).then(res => {
    ElMessage.success('编辑成功');
    GetMainTable();
  });
}
const changeOfStatus = (isAble = false, row) => {
  if (!isAble) {
    return;
  }
	return ElMessageBox.confirm(`是否确认${ row.status ? '关闭，关闭' : '开启，开启'} 【${ row.truename }】 后，${ row.status ? '禁止' : '允许'} 此用户登录系统`, '提示', {
		confirmButtonText: '确定',
		cancelButtonText: '取消',
		type: 'warning',
	}).then(() => {
		MainById({
			method: 'patch',
			id: row.id,
			data: {
				status: !row.status,
			}
		}).then(res => {
			ElMessage.success('操作成功');
			GetMainTable();
		});
	}).catch(() => {
		ElMessage.info('取消切换！');
	})
}
const handleMainDelete = (isAble = false, row) => {
  if (!isAble) {
    return;
  }
  ElMessageBox.confirm('', {
    message: h('div', null,[
      h('p',{ style:'font-size:16px;color: #4C4C4C;font-weight:500;'}, `您是否要删除 ${ row.truename }？`),
    ]),
    type: 'warning',
    confirmButtonText: '确认',
  }).then(() => {
    MainById({
      method: 'delete',
      id: row.id,
    }).then(res => {
      ElMessage.success('删除成功');
      GetMainTable();
    });
  }).catch(() => {
    ElMessage.info('已取消');
  });
}

/* 重置密码 */
const handleMainResetPassword = (isAble = false, row) => {
  if (!isAble) {
    return;
  }
  ElMessageBox.confirm('', {
    message: h('div', null,[
      h('p',{ style:'font-size:16px;color: #4C4C4C;font-weight:500;'}, `您是否要重置 ${ row.truename } 的密码？`),
    ]),
    type: 'warning',
    confirmButtonText: '确认',
  }).then(() => {
    let auth_user_w = {
      username: row.contract,
    };
    auth_user_w.password = Md5.hashStr('.ieieye.com' + row.contract.substr(-6, 6) + 'shhengji');
    MainById({
    	method: 'patch',
    	id: row.id,
    	data: {
        auth_user_w,
    	}
    }).then(res => {
    	ElMessage.success('操作成功');
    });
  }).catch(() => {
    ElMessage.info('已取消');
  });
}


/* 分配角色 */
const rightPopup = reactive({
  visible: false,
});
const rightForm = reactive({
  model: {},
  truename: '',
  
  roles_current: [],
  roles_others: [],
});
const rightFormRef = ref(null);
const handleRoles = (isAble = false, row) => {
  if (!isAble) {
    return;
  }
  rightPopup.visible = true;
  rightForm.model = {
    id: row.id,
  };
  
  const roleIds = Resd.roleList.map(i => i.id);
  const roleIdsSet = new Set(roleIds);
  const roles_current = [];
  const roles_others = [];
  for (const dept of row.project_roles) {
    if (roleIdsSet.has(dept)) {
      roles_current.push(dept);
    } else {
      roles_others.push(dept);
    }
  }
  rightForm.roles_current = roles_current;
  rightForm.roles_others = roles_others;
  
  rightForm.truename = row.truename;
}
const handleRoleCheck = (data, checkedArrs) => {
  /* 剔除当前节点的子孙辈id */
  const loIds = findLowIds(data);
  rightForm.roles_current = rightForm.roles_current.filter(item => !loIds.includes(item));
  /* 如果祖父辈已经勾选则当前选中无效 */
  const highIds = findHighIds(Resd.roleTree, data.id);
  if (rightForm.roles_current.some(item => highIds.includes(item))) {
    ElMessage.warning('已经选择了上级角色，您不必选择该角色');
    rightForm.roles_current = rightForm.roles_current.filter(item => item !== data.id);
  }
}
/* 递归获取当前节点的所有上级node的id */
const findHighIds = (tree, targetId) => {
  const path = [];
  const traverse = (nodes, ancestors) => {
    for (let node of nodes) {
      if (node.id === targetId) {
        path.push(...ancestors);
        return true;
      }
      if (node.children && node.children.length > 0) {
        if (traverse(node.children, [...ancestors, node.id])) {
          return true;
        }
      }
    }
    return false;
  }
  traverse(tree, []);
  return path;
}
/* 递归获取当前选择节点的children的所有角色id */
const findLowIds = (tree) => {
  let ids = [];
  const traverse = (node) => {
    ids.push(node.id);
    node.children?.forEach(child => traverse(child));
  }
  tree.children?.forEach(child => traverse(child));
  return ids;
}
const handleRolesSubmit = () => {
  MainById({
    method: 'patch',
    id: rightForm.model.id,
    data: {
      ...rightForm.model,
      project_roles: rightForm.roles_current.concat(rightForm.roles_others),
    }
  }).then(res => {
    ElMessage.success('编辑成功');
    GetMainTable();
  });
  rightPopup.visible = false;
}

/* 单体分配 */
const unitPopup = reactive({
  visible: false,
});
const unitForm = reactive({
  model: {},
  truename: '',
  isAll: true,
  units_flag_old: '',
  options: [],
  current: [],
  current_key: [],
  others: [],
});
const unitFormRef = ref(null);
const handleUnit = (isAble = false, row) => {
  if (!isAble) {
    return;
  }
  unitPopup.visible = true;
  unitForm.model = {
    id: row.id,
  };
  unitForm.truename = row.truename;
  
  /* 判断当前项目是否是全部unit权限 */
  unitForm.units_flag_old = row.units_flag;
  unitForm.isAll = true;
  if (row.units_flag) {
    const units_flag = JSON.parse(row.units_flag);
    if (units_flag.includes(curProject.id)) {
      unitForm.isAll = false;
    }
  }
  
  unitForm.current = [];
  unitForm.current_key = [];
  unitForm.options = [];
  Promise.all([loadUnitList(), getPosition()]).then(res => {
    unitForm.options = buildPositionUnitTree(res[0], res[1], false);
    
    const unitsIds = res[0].map(i => i.id);
    const unitsIdsSet = new Set(unitsIds);
    const units_current = [];
    const units_others = [];
    for (const dept of row.units) {
      if (unitsIdsSet.has(dept)) {
        units_current.push(dept);
      } else {
        units_others.push(dept);
      }
    }
    unitForm.current = units_current;
    unitForm.current_key = units_current.map(i => i + 'unit');
    unitForm.others = units_others;
  });
}
const isUnitAllChange = () => {
  if (unitForm.isAll) {
    unitForm.current = [];
  }
}
const loadUnitList = () => {
  return new Promise((resolve, reject) => {
    unitApi({
      method: 'get',
      params: {
        ordering: 'id',
      },
    }).then(res => {
      resolve(res.results || []);
    }).catch(e => {
      reject(e);
    });
  });
}
const getPosition = () => {
  return new Promise((resolve, reject) => {
    positionApi({
      method: 'get',
      params: {
        ordering: 'id',
      }
    }).then(res => {
      resolve(res.results || []);
    }).catch(e => {
      reject(e);
    });
  });
}
const unitsChange = (data, checked) => {
  unitForm.current = checked?.checkedNodes?.map(obj => obj.hasOwnProperty('positon') ? obj.id : null)?.filter(id => id !== null);
}
const unitsClear = () => {
  unitForm.current = [];
}
const handleUnitSubmit = () => {
  unitPopup.visible = false;
  const units_flag = getUnits_flag();
  MainById({
    method: 'patch',
    id: unitForm.model.id,
    data: {
      units_flag,
      units: unitForm.current.concat(unitForm.others),
    }
  }).then(res => {
    ElMessage.success('编辑成功');
    GetMainTable();
  });
}
const getUnits_flag = () => {
  if (!unitForm.units_flag_old && unitForm.isAll) {
    return '';
  }
  let arrs = unitForm.units_flag_old ? JSON.parse(unitForm.units_flag_old) : [];
  if (unitForm.isAll) {
    arrs = arrs.filter(i => curProject.id != i);
  } else if (!arrs.includes(curProject.id)) {
    arrs.push(curProject.id);
  }
  
  if (!arrs.length) {
    return '';
  }
  
  return JSON.stringify(arrs);
}
</script>

<template>
  <div class="flex-column mainCard">
    <el-form label-width="120px" class="flex t_form">
      <el-form-item label="姓名查询：">
        <el-input v-model="Filter.search" clearable></el-input>
      </el-form-item>
      <div class="flex r_btn">
        <el-button type="primary" @click="handleMainAdd(RIGHT['312'])" :disabled="!RIGHT['312']">
          新增
        </el-button>
      </div>
    </el-form>
    <el-table :data="MainTable.data" scrollbar-always-on>
      <el-table-column label="序号" type="index" align="center" width="100px" fixed="left"></el-table-column>
      <el-table-column label="姓名" prop="truename" min-width="120px" show-overflow-tooltip fixed="left"></el-table-column>
      <el-table-column label="登陆账号" prop="contract" min-width="130px" fixed="left"></el-table-column>
      <el-table-column label="角色" prop="project_roles" min-width="180px" show-overflow-tooltip :formatter="filterOthers"></el-table-column>
      <el-table-column label="状态">
        <template #default="scope">
        	<el-switch
            v-model="scope.row.status"
            class="ml-2"
            :before-change="() => { return changeOfStatus(RIGHT['313'], scope.row) }"
            :disabled="!RIGHT['313'] || curProject?.admin_user === scope.row.id"
          />
        </template>
      </el-table-column>
      <el-table-column label="创建时间" prop="create_time" min-width="160px"></el-table-column>
      <el-table-column label="上次登录时间" prop="last_login" min-width="160px">
        <template #default="scope">{{ scope.row.auth_user?.last_login }}</template>
      </el-table-column>
      <el-table-column label="登出时间" prop="logout_time" min-width="160px"></el-table-column>
      <el-table-column label="操作" fixed="right" width="260px">
        <template #default="scope">
          <template v-if="!(curProject?.admin_user === scope.row.id)">
            <el-button link type="primary" @click="handleMainEdit(RIGHT['313'], scope.row)" :disabled="!RIGHT['313']">
              编辑
            </el-button>
            <!-- <el-button link type="primary" @click="handleUnit(RIGHT['370'], scope.row)" :disabled="!RIGHT['370']">
              分配站点
            </el-button> -->
            <el-button link type="primary" @click="handleRoles(RIGHT['315'], scope.row)" :disabled="!RIGHT['315']">
              分配角色
            </el-button>
            <el-popover
              placement="bottom"
              popper-style="min-width: auto; padding: 5px 0;"
              :width="100"
              trigger="click"
            >
              <template #reference>
                <el-button type="primary" link>···</el-button>
              </template>
              <div class="flex-column">
                <el-button style="margin: 5px" link type="primary" @click="handleMainResetPassword(RIGHT['316'], scope.row)" :disabled="!RIGHT['316']">
                  重置密码
                </el-button>
                <el-button style="margin: 5px" link type="danger" @click="handleMainDelete(RIGHT['314'], scope.row)" :disabled="!RIGHT['314']">
                  删除
                </el-button>
              </div>
            </el-popover>
          </template>
        </template>
      </el-table-column>
    </el-table>
    <el-pagination
      layout="->, total, prev, pager, next, sizes"
      background
      :page-sizes="[10, 20, 30, 50, 100]"
      :pager-count="5"
      v-model:currentPage="Filter.page"
      v-model:page-size="Filter.pagesize"
      :total="MainTable.total"
    />
  </div>
  
  <!-- 新增编辑 -->
  <el-dialog width="500px" :title="MainPopup.type + '用户'" v-model="MainPopup.visible">
    <el-form
      ref="MainFormRef"
      :model="MainForm.model"
      label-width="120px"
    >
      <el-form-item prop="truename" label="用户名：" :rules="[{required: true, message: '不能为空', trigger: 'blur'},]">
        <el-input v-model="MainForm.model.truename"></el-input>
      </el-form-item>
      <el-form-item prop="contract" label="登陆账号：" :rules="[{required: true, message: '不能为空', trigger: 'blur'},]">
        <el-input placeholder="请输入手机号" v-model="MainForm.model.contract"></el-input>
        <el-tooltip content="初始密码为手机号后6位，账号发生修改会自动重置密码" placement="right">
          <div class="description flex-center-center pointer">?</div>
        </el-tooltip>
      </el-form-item>
      <el-form-item prop="departments" label="所属组织：" v-if="showDepartments">
        <div class="filter-tree">
          <el-tree-select
            placeholder="选择所属组织"
            node-key="id"
            :fit-input-width="true"
            :teleported="false"
            clearable
            collapse-tags
            collapse-tags-tooltip
            :render-after-expand="false"
            multiple
            default-expand-all
            :check-strictly="true"
            show-checkbox
            :highlight-current="true"
            :props="{label: 'name'}"
            v-model="MainForm.departments_current"
            :data="props.departmentTree"
          />
        </div>
      </el-form-item>
    </el-form>
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="MainPopup.visible = false">取 消</el-button>
        <el-button type="primary" @click="handleMainSubmit()">确 定</el-button>
      </span>
    </template>
  </el-dialog>
  
  <!-- 分配角色 -->
  <el-dialog width="500px" title="分配角色" v-model="rightPopup.visible">
    <el-form
      ref="rightFormRef"
      :model="rightForm.model"
      label-width="120px"
    >
      <el-form-item prop="truename" label="用户名：">
        {{ rightForm.truename }}
      </el-form-item>
      
      <el-form-item label="项目角色：">
        <div class="filter-tree">
          <el-tree-select
            ref="roleTreeRef"
            placeholder="选择项目角色"
            node-key="id"
            :fit-input-width="true"
            :teleported="false"
            clearable
            collapse-tags
            collapse-tags-tooltip
            :render-after-expand="false"
            multiple
            default-expand-all
            :check-strictly="true"
            show-checkbox
            :highlight-current="true"
            :props="{label: 'name'}"
            v-model="rightForm.roles_current"
            :data="Resd.roleTree"
            @check="handleRoleCheck"
          />
        </div>
      </el-form-item>
    </el-form>
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="rightPopup.visible = false">取 消</el-button>
        <el-button type="primary" @click="handleRolesSubmit()">确 定</el-button>
      </span>
    </template>
  </el-dialog>
  
  <!-- 站点分配 -->
  <el-dialog width="500px" title="站点分配" v-model="unitPopup.visible">
    <el-form
      ref="unitFormRef"
      :model="unitForm.model"
      label-width="120px"
    >
      <el-form-item prop="truename" label="用户名：">
        {{ unitForm.truename }}
      </el-form-item>
      <el-form-item prop="units" label="分配站点：">
        <div class="filter-tree">
          <el-radio-group v-model="unitForm.isAll" @change="isUnitAllChange()">
            <el-radio :value="true">全部站点</el-radio>
            <el-radio :value="false">部分站点</el-radio>
          </el-radio-group>
          <el-tree-select
            v-if="!unitForm.isAll"
            ref="treeRef"
            placeholder="请选择站点"
            node-key="key"
            :fit-input-width="true"
            :teleported="false"
            filterable
            clearable
            accordion
            collapse-tags
            collapse-tags-tooltip
            :render-after-expand="false"
            multiple
            show-checkbox
            :highlight-current="true"
            :props="{label: 'name'}"
            v-model="unitForm.current_key"
            :data="unitForm.options"
            @check="unitsChange"
            @clear="unitsClear"
          />
        </div>
      </el-form-item>
    </el-form>
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="unitPopup.visible = false">取 消</el-button>
        <el-button type="primary" @click="handleUnitSubmit()">确 定</el-button>
      </span>
    </template>
  </el-dialog>
</template>

<style lang="scss" scoped>
@use '@T2/styles/normal.scss';
.description {
  position: relative;
  width: 20px;
  height: 20px;
  background-color: #888888;
  border-radius: 50%;
  color: #ffffff;
  margin-left: 5px;
}
:deep(.el-select-dropdown__item) {
  margin-left: 3px;
}
.filter-tree {
  width: 90%;
  :deep(.el-select-dropdown) {
    .el-icon {
      font-size: 18px;
      margin-right: 5px;
    }
    .el-tree-node__content {
      height: 30px;
      cursor: default;
    }
    .el-select-dropdown__item {
      font-size: 15px;
    }
    .el-select-dropdown__wrap {
      max-height: 450px;
    }
  }
}
.form-title {
  font-weight: 600;
  font-size: 14px;
  position: relative;
  margin-bottom: 10px;
  padding-left: 10px;
  &::before {
    content: '';
    position: absolute;
    top: 50%;
    left: 0;
    height: 70%;
    background-color: #0055ff;
    width: 3px;
    transform: translateY(-50%);
  }
}
</style>